package top.codedance.iotp.common.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.io.*;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;

public class SystemUtil {

    /**
     * 获取执行程序当前目录
     *
     * @return
     */
    public static String getRuntimeDirPath(Class<?> clazz) {
        String path = clazz.getProtectionDomain().getCodeSource().getLocation().getPath();
        if (System.getProperty("os.name").contains("dows")) {
            path = path.substring(1, path.length());
        }
        if (path.endsWith(".jar")) {
            return path.substring(0, path.lastIndexOf("/") + 1);
        }
        return path.replace("classes/", "");
    }

    /**
     * 获取当前进程的线程数
     *
     * @return
     */
    public static int getCurrentProcessThreadCount() {
        ThreadGroup group = Thread.currentThread().getThreadGroup();
        ThreadGroup top = group;
        while (group != null) {
            top = group;
            group = group.getParent();
        }
        return top.activeCount();
    }

    /**
     * 获取用户目录路径
     * @return
     */
    public static String getUserHomeDirPath(){
        String strDir = System.getProperty("user.home");
        return strDir + File.separatorChar;
    }

    /**
     * 获取项目的用户根目录
     * @return
     */
    public static String getProjectUserDirPath(){
        return getUserHomeDirPath() + ".iot";
    }

    /**
     * 获取临时文件
     * @return
     */
    private static File getTempFile(String filename){
        String appDir = getProjectUserDirPath();
        File appDirFile = new File(appDir);
        if(!appDirFile.exists()){
            appDirFile.mkdirs();
        }
        File temp = new File(appDirFile.getAbsolutePath() + File.separatorChar + filename + ".tmp");
        return temp;
    }

    /**
     * 创建临时文件并写入数据
     *
     * @param filename
     * @param data
     */
    public static void genTempFile(String filename, String data) {
        try {
            File temp = getTempFile(filename);
            if(temp.exists()){
                temp.delete();
            }
            temp.createNewFile();
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(temp.getAbsolutePath()), StandardCharsets.UTF_8));
            out.write(data);
            out.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 读取监时文件内容
     *
     * @param filename
     * @return
     */
    public static String readTempFile(String filename) {
        try {
            StringBuilder sb = new StringBuilder();
            File file = getTempFile(filename);
            BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file.getAbsolutePath()), StandardCharsets.UTF_8));
            String str;
            while ((str = in.readLine()) != null)
                sb.append(str);
            in.close();
            return sb.toString();
        }catch (Exception ex){
            return null;
        }
    }

    /**
     * 读取指定文件内容
     *
     * @param filename
     * @return
     */
    public static String readFile(String filename) {
        return readFile(new File(filename));
    }

    /**
     * 读取指定文件内容
     *
     * @param file
     * @return
     */
    public static String readFile(File file) {
        try {
            if(!file.exists()){
                file.createNewFile();
            }
            StringBuilder sb = new StringBuilder();
            BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
            String str;
            while ((str = in.readLine()) != null)
                sb.append(str + "\n");
            in.close();
            return sb.toString();
        }catch (Exception ex){
            return null;
        }
    }

    /**
     * 读取指定文件内容到列表
     *
     * @param filename
     * @return
     */
    public static ArrayList<String> readFileToList(String filename) {
        return readFileToList(new File(filename));
    }

    /**
     * 读取指定文件内容到列表
     *
     * @param file
     * @return
     */
    public static ArrayList<String> readFileToList(File file) {
        ArrayList<String> results = new ArrayList<>();
        try {
            BufferedReader in = new BufferedReader(new FileReader(file));
            String line;
            while ((line = in.readLine()) != null)
                if(!line.isEmpty())
                    results.add(line);
            in.close();
        }catch (Exception ex){}
        return results;
    }

    /**
     * 写入内容到指定文件
     *
     * @param filename
     * @param data
     * @return
     */
    public static void writeFile(String filename, String data) {
        writeFile(new File(filename), data);
    }

    /**
     * 写入内容到指定文件
     *
     * @param file
     * @param data
     * @return
     */
    public static void writeFile(File file, String data) {
        try {
            if(!file.exists()) {
                file.createNewFile();
            }
            FileOutputStream out = new FileOutputStream(file);
            out.write(data.getBytes(StandardCharsets.UTF_8));
            out.flush();
            out.close();
        }catch (Exception ex){}
    }

    /**
     * 读取监时文件内容到列表
     *
     * @param filename
     * @return
     */
    public static ArrayList<String> readTempFileToList(String filename) {
        ArrayList<String> results = new ArrayList<>();
        try {
            File file = getTempFile(filename);
            BufferedReader in = new BufferedReader(new FileReader(file));
            String line;
            while ((line = in.readLine()) != null)
                if(!line.isEmpty())
                    results.add(line);
            in.close();
        }catch (Exception ex){}
        return results;
    }

    public static boolean pingIp(String ip) throws IOException {
        //能ping通放回true 反之 false 超时时间 3000毫秒
        return InetAddress.getByName(ip).isReachable(5000);
    }

    public static boolean checkPort(String ip, Integer port) {
        Socket connect = new Socket();
        boolean res = false;
        try {
            connect.connect(new InetSocketAddress(ip, port), 1000);//建立连接
            //能telnet通返回true，否则返回false
            res = connect.isConnected();//通过现有方法查看连通状态
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                connect.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return res;
    }

    /**
     * 些方法只适合手动安装的jdk中的java命令执行的java程序
     * @return
     */
    public static String getJaveHome(){
        RuntimeMXBean mxb = ManagementFactory.getRuntimeMXBean();
        String bootClassPath = mxb.getBootClassPath();
        String[] split = bootClassPath.split(File.pathSeparator);
        return split[0].replaceAll("jre.*", "");
    }

    /**
     * 获取负载信息
     * @return
     */
    public static JSONObject getSystemUsage(){
        OperatingSystemMXBean osb = ManagementFactory.getOperatingSystemMXBean();
        String s = JSON.toJSONString(osb);
        JSONObject obj = JSON.parseObject(s);
        JSONObject result = new JSONObject();
        result.put("cpu", Math.round(obj.getDoubleValue("processCpuLoad") * 100));
        result.put("system_cpu", Math.round(obj.getDoubleValue("systemCpuLoad") * 100));
        long GB = 1024 * 1024 * 1024;
        result.put("total_mem", Math.round(1.0 * obj.getLong("totalPhysicalMemorySize") / GB));
        result.put("free_mem", Math.round(1.0 * obj.getLong("freePhysicalMemorySize") / GB));
        result.put("mem", Math.round(1.0 * (result.getDouble("total_mem") - result.getDouble("free_mem")) / result.getDouble("total_mem") * 100));
        return result;
    }
}
